using HZY.Framework.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using System.Runtime.InteropServices;

namespace HZY.Core.UploadFile;

public class FileManager : IFileManager, ITransientDependency
{
    private readonly IWebHostEnvironment _webHostEnvironment;
    private readonly FileOptions _fileOptions;
    private readonly FileManagerContext _fileManagerContext;

    public FileManager(IWebHostEnvironment webHostEnvironment, FileOptions fileOptions)
    {
        _webHostEnvironment = webHostEnvironment;
        _fileOptions = fileOptions;
        _fileManagerContext = new FileManagerContext();
        Init();
    }

    private void Init()
    {
        _fileManagerContext.MaxFileSizeLimit = _fileOptions.GetMaxFileSizeLimit();
        if (string.IsNullOrWhiteSpace(_fileOptions.AllowExtensions) || _fileOptions.AllowExtensions == "*")
        {
            _fileManagerContext.IsAllowAnyFile = true;
        }
        else
        {
            _fileManagerContext.FileExtensions = _fileOptions.AllowExtensions.Split("|").Select(s => s.ToLower()).ToList();
        }

        _fileManagerContext.ServerUrl = _fileOptions.ServerUrl;
        _fileManagerContext.RequestPath = _fileOptions.RequestPath;
        _fileManagerContext.FileDir = GetFilePath(_fileOptions.DirectoryUrl);
    }

    /// <summary>
    /// 获取配置的文件路径
    /// </summary>
    /// <param name="dir"></param>
    /// <returns></returns>
    private string GetFilePath(string dir)
    {
        if (IsPathRooted(dir))
        {
            return dir;
        }

        return Path.Combine(_webHostEnvironment.WebRootPath, dir);
    }

    /// <summary>
    /// 判断地址是否是根路径
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    private static bool IsPathRooted(string path)
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            return Path.IsPathRooted(path);
        }
        else
        {
            return path.StartsWith('/'); // Linux 判断
        }
    }

    /// <summary>
    /// 设置追加目录
    /// </summary>
    /// <param name="dir"></param>
    /// <returns></returns>
    public FileManager AddSaveFolder(string dir)
    {
        dir = RemoveStartWith(dir);

        _fileManagerContext.FileDir += dir;
        _fileManagerContext.RequestPath += dir;
        if (!Directory.Exists(_fileManagerContext.FileDir))
        {
            Directory.CreateDirectory(_fileManagerContext.FileDir);
        }

        return this;
    }

    /// <summary>
    /// 设置上传最大长度
    /// </summary>
    /// <param name="maxLength"></param>
    /// <returns></returns>
    public FileManager AddMaxLength(long maxLength)
    {
        _fileManagerContext.MaxFileSizeLimit = maxLength;
        return this;
    }

    /// <summary>
    /// 设置上传最大长度
    /// </summary>
    /// <param name="maxLength"></param>
    /// <returns></returns>
    public FileManager AddMaxLength(string maxLength)
    {
        _fileManagerContext.MaxFileSizeLimit = maxLength.ToStorageByteLength();
        return this;
    }

    /// <summary>
    /// 允许所有文件格式
    /// </summary>
    /// <returns></returns>
    public FileManager AllowAnyFileExtensions()
    {
        _fileManagerContext.IsAllowAnyFile = true;
        return this;
    }

    /// <summary>
    /// 追加允许文件格式
    /// </summary>
    /// <param name="fileExtensions"></param>
    /// <returns></returns>
    public FileManager AddFileExtensions(params string[] fileExtensions)
    {
        foreach (var fileExtension in fileExtensions)
        {
            if (!_fileManagerContext.FileExtensions.Contains(fileExtension.ToLower()))
            {
                _fileManagerContext.FileExtensions.Add(fileExtension.ToLower());
            }
        }

        return this;
    }

    /// <summary>
    /// 重置文件格式
    /// </summary>
    /// <returns></returns>
    public FileManager ResetFileExtensions()
    {
        _fileManagerContext.FileExtensions.Clear();
        return this;
    }

    /// <summary>
    /// 构建FileManagerContext
    /// </summary>
    /// <returns></returns>
    public FileManagerContext BuildFileManagerContext()
    {
        return _fileManagerContext;
    }

    /// <summary>
    /// 获取网络路径
    /// </summary>
    /// <returns></returns>
    public string GetServerUrl()
    {
        return _fileOptions.ServerUrl;
    }

    private static string RemoveStartWith(string str)
    {
        if (str.StartsWith('/') || str.StartsWith('\\'))
        {
            return str[1..];
        }

        return str;
    }
}